﻿using Castle.DynamicProxy;
using CNKI.TPI.Web.Base;
using CNKI.TPI.Web.Search.IBLL;
using CNKI.TPI.Web.Search.Model;
using CNKI.TPI.Web.UI.Filters;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.SessionState;

namespace CNKI.TPI.Web.UI.Controllers.Search
{
    [SessionState(SessionStateBehavior.ReadOnly)]
    public class FileController : BaseController
    {
        private IFileService fileService;
        private ISearchService searchService;
        public FileController(IFileService fileService, ISearchService searchService)
        {
            this.fileService = generator.CreateInterfaceProxyWithTarget<IFileService>(fileService, new IInterceptor[] { new LogInterceptor() });
            this.searchService = generator.CreateInterfaceProxyWithTarget<ISearchService>(searchService, new IInterceptor[] { new LogInterceptor() });
        }

        /// <summary>
        /// 读取视频文件
        /// </summary>
        /// <param name="dbId"></param>
        /// <param name="fileId"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public FileStreamResult GetStream(int dbId, int fileId, string key, MediaType type)
        {
            string filePath = null;
            string fileType = null;
            string fileName = null;
            try
            {
                if (!(EncryptHelper.Encrypt(dbId.ToString() + fileId.ToString()) == HttpUtility.UrlEncode(key)))
                {
                    Response.Redirect("~/Error");
                    return null;
                }
                filePath = fileService.GetDigitalFile(dbId, fileId);
                if (String.IsNullOrEmpty(filePath) || !System.IO.File.Exists(filePath))
                {
                    Response.Redirect("~/Error");
                    return null;
                }
                fileType = filePath.Substring(filePath.IndexOf(".") + 1);
                fileName = filePath.Substring(filePath.LastIndexOf("\\") + 1);
                Response.BufferOutput = false;
            }
            catch (Exception ex)
            {
                LogOpr.Error(ex.ToString());

            }

            if (type == MediaType.Audio)
            {
                if (fileType.Trim().ToLower() == "mp3")
                {
                    fileType = "mpeg";
                }

                return File(new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read), "audio/" + fileType, HttpContext.Request.Browser.Browser == "IE" ? Url.Encode(fileName) : fileName);
            }
            else
            {
                return File(new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read), "video/" + fileType, HttpContext.Request.Browser.Browser == "IE" ? Url.Encode(fileName) : fileName);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbId"></param>
        /// <param name="recordId"></param>
        /// <param name="key"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public FileStreamResult GetFirstStream(int dbId, int recordId, string key, MediaType type)
        {
            string fileType = null;
            string filePath = null;
            string fileName = null;
            try
            {
                if (!(EncryptHelper.Encrypt(dbId.ToString() + recordId.ToString()) == HttpUtility.UrlEncode(key)))
                {
                    Response.Redirect("~/Error");
                    return null;
                }
                ////获得文件路径
                filePath = fileService.GetFirstDigitalFileByType(dbId, recordId, type);
                if (String.IsNullOrEmpty(filePath) || !System.IO.File.Exists(filePath))
                {
                    Response.Redirect("~/Error");
                    return null;
                }
                fileType = filePath.Substring(filePath.IndexOf(".") + 1);
                fileName = filePath.Substring(filePath.LastIndexOf("\\") + 1);
                Response.BufferOutput = false;
            }
            catch (Exception ex)
            {
                LogOpr.Error(ex.ToString());

            }
            if (type == MediaType.Audio)
            {
                if (fileType.Trim().ToLower() == "mp3")
                {
                    fileType = "mpeg";
                }
                return File(new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read), "video/" + fileType, HttpContext.Request.Browser.Browser == "IE" ? Url.Encode(fileName) : fileName);
            }
            else
            {
                return File(new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read), "video/" + fileType, HttpContext.Request.Browser.Browser == "IE" ? Url.Encode(fileName) : fileName);
            }

        }

        //private void DealMedia(string filePath)
        //{

        //    string range = GetHeader("Range");
        //    long startIndex = 0;
        //    long endIndex = 0;


        //    if (string.IsNullOrEmpty(range))
        //    {

        //        Response.StatusCode = (int)HttpStatusCode.OK;
        //        var video = new VideoStream(filePath, startIndex, endIndex);
        //        Response.Headers.Add("Accept-Range", "bytes");
        //        //response.Content.Headers.Add("Content-Length", video.FileLength.ToString());
        //        Action<Stream, HttpContent, TransportContext> send = video.WriteToStream;
        //        string fileType = filePath.Substring(filePath.IndexOf(".") + 1);
        //        if ("mov".Equals(fileType.ToLower()))
        //        {
        //            fileType = "quicktime";
        //        }
        //        Response.Content = new System.Net.Http.PushStreamContent(send, new MediaTypeHeaderValue("video/" + fileType));
        //        //response.Content.Headers.Add("Accept-Range", "bytes");
        //        Response.Content.Headers.Add("Content-Length", video.ReadLength.ToString());
        //        //response.Content.Headers.Add("Content-Range", string.Format("bytes {0}-{1}/{2}", startIndex, endIndex == 0 ? video.ReadLength - 1 : endIndex, video.FileLength));

        //    }
        //    else
        //    {
        //        range = range.Substring(6);
        //        string[] rangeArray = range.Split(new[] { '-' }, StringSplitOptions.RemoveEmptyEntries);
        //        if (1 == rangeArray.Length)
        //        {
        //            startIndex = long.Parse(rangeArray[0]);
        //        }
        //        else
        //        {
        //            startIndex = long.Parse(rangeArray[0]);
        //            endIndex = long.Parse(rangeArray[1]);
        //        }

        //        Response.StatusCode = (int)HttpStatusCode.PartialContent;
        //        var video = new VideoStream(filePath, startIndex, endIndex);
        //        Action<Stream, HttpContent, TransportContext> send = video.WriteToStream;
        //        string fileType = filePath.Substring(filePath.IndexOf(".") + 1);
        //        if ("mov".Equals(fileType.ToLower()))
        //        {
        //            fileType = "quicktime";
        //        }
        //        Response.Content = new System.Net.Http.PushStreamContent(send, new MediaTypeHeaderValue("video/" + fileType));
        //        Response.Headers.Add("Accept-Range", "bytes");
        //        Response.Headers.Add("Content-Length", video.ReadLength.ToString());
        //        Response.Headers.Add("Content-Range", string.Format("bytes {0}-{1}/{2}", startIndex, endIndex == 0 ? video.ReadLength - 1 : endIndex, video.FileLength));
        //    }
        //}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbId"></param>
        /// <param name="recordId"></param>
        /// <param name="key"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public FilePathResult GetFirstDigitalFileByType(int dbId, int recordId, string key, MediaType type)
        {
            if (!(EncryptHelper.Encrypt(dbId.ToString() + recordId.ToString()) == HttpUtility.UrlEncode(key)))
            {
                Response.Redirect("~/Error");
                return null;
            }
            string filePath = fileService.GetFirstDigitalFileByType(dbId, recordId, type);
            string fileName = filePath.Substring(filePath.LastIndexOf("\\") + 1);
            if (String.IsNullOrEmpty(filePath) || !System.IO.File.Exists(filePath))
            {
                Response.Redirect("~/Error");
                return null;
            }
            return File(filePath, "application/octet-stream", HttpContext.Request.Browser.Browser == "IE" ? Url.Encode(fileName) : fileName);
        }

        public FilePathResult GetFirstDigitalFile(int dbId, int recordId, string key,int downtype)
        {
            try
            {
                if (!(EncryptHelper.Encrypt(dbId.ToString() + recordId.ToString()) == HttpUtility.UrlEncode(key)))
                {
                    Response.Redirect("~/Error");
                    return null;
                }
                bool m = SessionHelper.HasDownloadRight(dbId);
                if (!m)//有下载权限则判断文件是否存在
                {
                    return null;
                }
                
                string filePath = fileService.GetFirstDigitalFile(dbId, recordId);
                string fileName = filePath.Substring(filePath.LastIndexOf("\\") + 1);
                if (String.IsNullOrEmpty(filePath) || !System.IO.File.Exists(filePath))
                {
                    Response.Redirect("~/Error");
                    return null;
                }
                SYS_CMS_DATABASE obj = searchService.GetDataByID(dbId);//获取数据库编码
                IList<METADATA_FILE> objfile = fileService.GetFile(recordId, obj.DatabaseCode); //获取文件ID
                LogOpr.Download(dbId.ToString(), obj.DatabaseCode, recordId.ToString(), objfile[0].SYSID.ToString(), downtype, fileName);
                return File(filePath, "application/octet-stream", HttpContext.Request.Browser.Browser == "IE" ? Url.Encode(fileName) : fileName);
            }
            catch (Exception e)
            {
                LogOpr.Error(e.Message);
                return null;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbId"></param>
        /// <param name="fileId"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public FilePathResult GetDigitalFile(int dbId, int fileId, string key, int downtype, string recordid)
        {
            try
            {
                if (!(EncryptHelper.Encrypt(dbId.ToString() + fileId.ToString()) == HttpUtility.UrlEncode(key)))
                {
                    Response.Redirect("~/Error");
                    return null;
                }
                string filePath = fileService.GetDigitalFile(dbId, fileId);
                if (String.IsNullOrEmpty(filePath) || !System.IO.File.Exists(filePath))
                {
                    Response.Redirect("~/Error");
                    return null;
                }
                string fileName = filePath.Substring(filePath.LastIndexOf("\\") + 1);
                SYS_CMS_DATABASE obj = searchService.GetDataByID(dbId);
                LogOpr.Download(dbId.ToString(), obj.DatabaseCode,recordid,fileId.ToString(),downtype, fileName);
                return File(filePath, "application/octet-stream", HttpContext.Request.Browser.Browser == "IE" ? Url.Encode(fileName) : fileName);
            }
            catch(Exception e)
            {
                LogOpr.Error(e.Message);
                return null;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbId"></param>
        /// <param name="fileId"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public FilePathResult GetDigitalPic(int dbId, int fileId, string key)
        {
            if (!(EncryptHelper.Encrypt(dbId.ToString() + fileId.ToString()) == HttpUtility.UrlEncode(key)))
            {
                //Response.Redirect("~/Error");
                //return null;
                return DefaultPic();
            }
            string imgPath = fileService.GetDigitalFile(dbId, fileId);
            if (String.IsNullOrEmpty(imgPath) || !System.IO.File.Exists(imgPath))
            {
                //Response.Redirect("~/Error");
                //return null;
                return DefaultPic();
            }
            string fileType = imgPath.Substring(imgPath.IndexOf(".") + 1);
            string fileName = imgPath.Substring(imgPath.LastIndexOf("\\") + 1);
            if (fileType.ToLower() == "jpg")
            {
                fileType = "jpeg";
            }
            return File(imgPath, "image/" + fileType, "");
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbId"></param>
        /// <param name="fileId"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public FilePathResult GetSmallPic(int dbId, int fileId, string key)
        {
            if (!(EncryptHelper.Encrypt(dbId.ToString() + fileId.ToString()) == HttpUtility.UrlEncode(key)))
            {
                //Response.Redirect("~/Error");
                //return null;
                return DefaultPic();
            }
            string imgPath = fileService.GetSmallPic(dbId, fileId);
            if (String.IsNullOrEmpty(imgPath) || !System.IO.File.Exists(imgPath))
            {
                //Response.Redirect("~/Error");
                //return null;
                return DefaultPic();
            }
            string fileType = imgPath.Substring(imgPath.IndexOf(".") + 1);
            string fileName = imgPath.Substring(imgPath.LastIndexOf("\\") + 1);
            if (fileType.ToLower() == "jpg")
            {
                fileType = "jpeg";
            }
            return File(imgPath, "image/" + fileType, HttpContext.Request.Browser.Browser == "IE" ? Url.Encode(fileName) : fileName);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbId"></param>
        /// <param name="recordId"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public FilePathResult GetFirstSmallPic(int dbId, int recordId, string key)
        {
            if (!(EncryptHelper.Encrypt(dbId.ToString() + recordId.ToString()) == HttpUtility.UrlEncode(key)))
            {
                //Response.Redirect("~/Error");
                //return null;
                return DefaultPic();
            }
            string imgPath = fileService.GetFirstSmallPic(dbId, recordId);
            if (String.IsNullOrEmpty(imgPath) || !System.IO.File.Exists(imgPath))
            {
                //Response.Redirect("~/Error");
                //return null;
                return DefaultPic();
            }
            string fileType = imgPath.Substring(imgPath.IndexOf(".") + 1);
            string fileName = imgPath.Substring(imgPath.LastIndexOf("\\") + 1);
            if (fileType.ToLower() == "jpg")
            {
                fileType = "jpeg";
            }
            return File(imgPath, "image/" + fileType, HttpContext.Request.Browser.Browser == "IE" ? Url.Encode(fileName) : fileName);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbId"></param>
        /// <param name="recordId"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public FilePathResult GetFirstDigitalPic(int dbId, int recordId, string key)
        {
            if (!(EncryptHelper.Encrypt(dbId.ToString() + recordId.ToString()) == HttpUtility.UrlEncode(key)))
            {
                //Response.Redirect("~/Error");
                //return null;
                return DefaultPic();
            }
            string imgPath = fileService.GetFirstDigitalFileByType(dbId, recordId, MediaType.Pic);
            if (String.IsNullOrEmpty(imgPath) || !System.IO.File.Exists(imgPath))
            {
                //Response.Redirect("~/Error");
                //return null;
                return DefaultPic();
            }
            string fileType = imgPath.Substring(imgPath.IndexOf(".") + 1);
            string fileName = imgPath.Substring(imgPath.LastIndexOf("\\") + 1);
            if (fileType.ToLower() == "jpg")
            {
                fileType = "jpeg";
            }
            return File(imgPath, "image/" + fileType, HttpContext.Request.Browser.Browser == "IE" ? Url.Encode(fileName) : fileName);
        }

        private void getParam(out int dbID, out MediaType type)
        {
            dbID = 0;
            type = 0;
            if (!String.IsNullOrEmpty(Request.QueryString["dbID"]))
            {
                dbID = int.Parse(Request.QueryString["dbID"]);
            }
            if (!String.IsNullOrEmpty(Request.QueryString["MediaType"]))
            {
                type = (MediaType)int.Parse(Request.QueryString["MediaType"]);
            }
        }

        /// <summary>
        /// 音频，视频 页面加载时判断文件是否存在，类型是否支持
        /// </summary>
        /// <param name="dbID"></param>
        /// <param name="?"></param>
        /// <returns></returns>
        public string IsFirstDigitalFileExsit()
        {
            int dbID;
            int recordId = 0;
            MediaType type;
            if (!String.IsNullOrEmpty(Request.QueryString["recordId"]))
            {
                recordId = int.Parse(Request.QueryString["recordId"]);
            }
            getParam(out dbID, out type);
            string filePath = fileService.GetFirstDigitalFileByType(dbID, recordId, type);//获取路径
            return fileService.ParseFile(type, filePath);//是否支持
        }

        /// <summary>
        /// 播放列表点击时，判断文件是否存在，类型是否支持
        /// </summary>
        /// <param name="dbID"></param>
        /// <param name="?"></param>
        /// <returns></returns>
        public string IsDigitalFileExsit()
        {
            int dbID;
            int fileID = 0;
            MediaType type;
            if (!String.IsNullOrEmpty(Request.QueryString["fileID"]))
            {
                fileID = int.Parse(Request.QueryString["fileID"]);
            }
            getParam(out dbID, out type);
            string filePath = fileService.GetDigitalFile(dbID, fileID);
            return fileService.ParseFile(type, filePath);
        }

        /// <summary>
        /// 判断是否有下载权限，文件是否存在
        /// </summary>
        /// <param name="dbId"></param>
        /// <param name="recordID"></param>
        /// <param name="type"></param>
        public string IsShowDown()
        {
            int dbID;
            int recordId = 0;
            int fileid = 0;
            int downtype = (int)DownFromType.CommonDown;
            MediaType type;
            getParam(out dbID, out type);
            string downloadUrl = "";
            if (!String.IsNullOrEmpty(Request.QueryString["recordId"]))
            {
                recordId = int.Parse(Request.QueryString["recordId"]);
            }
            if (!String.IsNullOrEmpty(Request.QueryString["fileid"]))
            {
                fileid = int.Parse(Request.QueryString["fileid"]);
            }
            if (!String.IsNullOrEmpty(Request.QueryString["downType"]))
            {
                downtype = int.Parse(Request.QueryString["downType"]);
            }
            string strMessage = "1";
            //是否有下载权限
            bool m = SessionHelper.HasDownloadRight(dbID);
            if (m)//有下载权限则判断文件是否存在
            {
                if (downtype == (int)DownFromType.AuditDown) //审核模式下载不用判断下载量是否超出
                {
                    strMessage = IsFileExsit(dbID, recordId, fileid);
                }
                else
                {
                    int status = fileService.GetFileDownloadLimiteInfo(dbID);//正常下载判断下载量是否超出
                    if (0 == status)
                    {
                        strMessage = IsFileExsit(dbID, recordId, fileid);
                    }
                    else if (1 == status)
                    {
                        strMessage = "已超过当日下载量！";
                    }
                    else if (2 == status)
                    {
                        strMessage = "已超过最大下载量！";
                    }
                }
            }
            else
            {
                strMessage = "您没有下载权限！";
                if (SessionHelper.IsUserInfoExsit())
                {
                    bool anonymousControlFlag = ConfigHelper.IsAnonymousControlEnabled();
                    string anonymousUsername = ConfigHelper.GetAnonymousAccount();
                    LoginUserInfo userInfo = SessionHelper.GetUserInfo();
                    if (anonymousControlFlag && (anonymousUsername.Equals(userInfo.UserCode)))
                    {
                        strMessage = "2";//匿名，先登录在下载权限
                    }
                }
            }
            if (strMessage == "1" || strMessage == "2")
            {
                if (fileid == -1)
                {
                    downloadUrl = ResourceHelper.GetFileDownloadURLByRecoredId(dbID, recordId, downtype);
                }
                else
                {
                    downloadUrl = ResourceHelper.GetFileDownloadURL(dbID, fileid, recordId, downtype);
                }
            }
            return "[{\"status\":\"" + strMessage + "\",\"url\":\"" + downloadUrl + "\"}]";
        }
        /// <summary>
        /// 是否有在线预览的权限
        /// </summary>
        /// <param name="dbId"></param>
        /// <param name="recordID"></param>
        /// <param name="type"></param>
        public string IsShowBrowse()
        {
            int dbID;
            int recordId = 0;
            MediaType type;
            int fileid = -1;
            string downloadUrl = "";
            string dbName = "";
            int downtype = (int)DownFromType.CommonDown;
            getParam(out dbID, out type);
            if (!String.IsNullOrEmpty(Request.QueryString["dbName"]))
            {
                dbName = Request.QueryString["dbName"];
            }
            if (!String.IsNullOrEmpty(Request.QueryString["recordId"]))
            {
                recordId = int.Parse(Request.QueryString["recordId"]);
            }
            if (!String.IsNullOrEmpty(Request.QueryString["fileid"]))
            {
                fileid = int.Parse(Request.QueryString["fileid"]);
            }
            if (!String.IsNullOrEmpty(Request.QueryString["downtype"]))
            {
                downtype = int.Parse(Request.QueryString["downtype"]);
            }
            string strMessage = "1";
            //是否有在线预览权限
            bool m = SessionHelper.HasBrowseRight(dbID);
            if (m)//有权限则判断文件是否存在
            {
                //int status = fileService.GetFileDownloadLimiteInfo(dbID);//判断下载量是否超出
                //if (0 == status)
                //{
                    // 在线预览需要再次过滤文件类型
                    string filePath = "";
                    if (fileid == -1)
                    {
                        filePath = fileService.GetFirstDigitalFile(dbID, recordId);
                    }
                    else
                    {
                        filePath = fileService.FileIsExitByFileID(dbID, fileid);
                    }
                    string flage = fileService.ParseFile(MediaType.Doc, filePath);
                    if (flage == "0")
                    {
                        strMessage = "文件不存在！";
                    }
                    else if (flage == "2")
                    {
                        strMessage = "不支持该类型！";
                    }
                //}
                //else if (1 == status)
                //{
                //    strMessage = "已超过当日下载量！";
                //}
                //else if (2 == status)
                //{
                //    strMessage = "已超过最大下载量！";
                //}

            }
            else
            {
                strMessage = "您没有在线预览权限！";
                if (SessionHelper.IsUserInfoExsit())
                {
                    bool anonymousControlFlag = ConfigHelper.IsAnonymousControlEnabled();
                    string anonymousUsername = ConfigHelper.GetAnonymousAccount();
                    LoginUserInfo userInfo = SessionHelper.GetUserInfo();
                    if (anonymousControlFlag && (anonymousUsername.Equals(userInfo.UserCode)))
                    {
                        strMessage = "2";
                    }
                }
            }
            if (strMessage == "1" || strMessage == "2")
            {
                downloadUrl = Url.Action("DocView", "DocResource", new { dbName = dbName, resourceId = fileid, recordId = recordId, dbId = dbID, downType = downtype });
            }
            return "[{\"status\":\"" + strMessage + "\",\"url\":\"" + downloadUrl + "\"}]";
        }
        private FilePathResult DefaultPic()
        {
            return File(System.Web.HttpContext.Current.Server.MapPath("~/Images/nopic1.gif"), "image/gif", "defalutpic");

        }
        /// <summary>
        /// 判断文件是否存在
        /// </summary>
        /// <param name="dbId"></param>
        /// <param name="recordID"></param>
        /// <param name="fileid"></param>
        /// <returns></returns>
        private string IsFileExsit(int dbId, int recordID, int fileid)
        {
            string flage = "1";
            string filePath = "";
            try
            {
                if (fileid == -1)
                {
                    filePath = fileService.GetFirstDigitalFile(dbId, recordID);
                }
                else
                {
                    filePath = fileService.FileIsExitByFileID(dbId, fileid);
                }
                if (!ResourceHelper.CheckFileExist(filePath))
                {
                    flage = "文件不存在！";
                }
            }
            catch
            {
                flage = "系统异常，请刷新重试！";
            }
            return flage;
        }

        public string CheckFileExist(string path, string key)
        {
            if (!(EncryptHelper.Encrypt(path) == HttpUtility.UrlEncode(key)))
            {
                return "false";
            }
            if (String.IsNullOrEmpty(path) || !System.IO.File.Exists(path))
            {
                return "false";
            }
            else
            {
                return "true";
            }
        }
    }
}
